<?php
class FileUpload {
private $filepath;     //指定上传文件保存的路径
private $allowtype=array('gif', 'jpg', 'png', 'jpeg');  //充许上传文件的类型
private $maxsize=1000000;  //允上传文件的最大长度 1M
private $israndname=true;  //是否随机重命名， true false不随机，使用原文件名
private $originName;   //源文件名称
private $tmpFileName;   //临时文件名
private $fileType;  //文件类型
private $fileSize;  //文件大小
private $newFileName; //新文件名
private $errorNum=0;  //错误号
private $errorMess=""; //用来提供错误报告

//用于对上传文件初使化
//1. 指定上传路径， 2，充许的类型， 3，限制大小， 4，是否使用随机文件名称
//让用户可以不用按位置传参数，后面参数给值不用将前几个参数也提供值
function __construct($options=array()){
foreach($options as $key=>$val){
$key=strtolower($key);
//查看用户参数中数组的下标是否和成员属性名相同
if(!in_array($key,get_class_vars(get_class($this)))){
continue;
}

$this->setOption($key, $val);
}
 
}

private function getError(){
$str="上传文件<font color='red'>{$this->originName}</font>时出错：";

switch($this->errorNum){
case 4: $str .= "没有文件被上传"; break;
case 3: $str .= "文件只被部分上传"; break;
case 2: $str .= "上传文件超过了HTML表单中MAX_FILE_SIZE选项指定的值"; break;
case 1: $str .= "上传文件超过了php.ini 中upload_max_filesize选项的值"; break;
case -1: $str .= "末充许的类型"; break;
case -2: $str .= "文件过大，上传文件不能超过{$this->maxSize}个字节"; break;
case -3: $str .= "上传失败"; break;
case -4: $str .= "建立存放上传文件目录失败，请重新指定上传目录"; break;
case -5: $str .= "必须指定上传文件的路径"; break;

default: $str .=  "末知错误";
}

return $str.'<br>';
}
//用来检查文件上传路径
private function checkFilePath(){
if(empty($this->filepath)) {
$this->setOption('errorNum', -5);
return false;
}

if(!file_exists($this->filepath) || !is_writable($this->filepath)){
if(!@mkdir($this->filepath, 0755)){
$this->setOption('errorNum', -4);
return false;
}
}
return true;
}
//用来检查文件上传的大小
private function checkFileSize() {
if($this->fileSize > $this->maxsize){
$this->setOPtion('errorNum', '-2');
return false;
}else{
return true;
}
}

//用于检查文件上传类型
private function checkFileType() {
if(in_array(strtolower($this->fileType), $this->allowtype)) {
return true;
}else{
$this->setOption('errorNum', -1);
return false;
}
}
//设置上传后的文件名称
private function setNewFileName(){
if($this->israndname){
$this->setOption('newFileName', $this->proRandName());
} else {
$this->setOption('newFileName', $this->originName);
}
}

//设置随机文件名称
private function proRandName(){
$fileName=date("YmdHis").rand(100,999);
return $fileName.'.'.$this->fileType;
}
private function setOption($key, $val){
$this->$key=$val;
}
//用来上传一个文件
function uploadFile($fileField){
$return=true;
//检查文件上传路径
if(!$this->checkFilePath()){
$this->errorMess=$this->getError();
return false;
}

$name=$_FILES[$fileField]['name'];
$tmp_name=$_FILES[$fileField]['tmp_name'];
$size=$_FILES[$fileField]['size'];
$error=$_FILES[$fileField]['error'];

if(is_Array($name)){
$errors=array();

for($i=0; $i<count($name); $i++){
if($this->setFiles($name[$i], $tmp_name[$i], $size[$i], $error[$i])){
if(!$this->checkFileSize() || !$this->checkFileType()){
$errors[]=$this->getError();
$return=false;
}
}else{
$error[]=$this->getError();
$return=false;
}

if(!$return)
$this->setFiles();
}

if($return){
$fileNames=array();

for($i=0; $i<count($name); $i++){
if($this->setFiles($name[$i], $tmp_name[$i], $size[$i], $error[$i])){
$this->setNewFileName();
if(!$this->copyFile()){
$errors=$this->getError();
$return=false;
}else{
$fileNames[]=$this->newFileName;
}
}
}

$this->newFileName=$fileNames;
}

$this->errorMess=$errors;
return $return;
} else {
if($this->setFiles($name, $tmp_name, $size, $error)){
if($this->checkFileSize() && $this->checkFileType()){
$this->setNewFileName();

if($this->copyFile()){
return true;
}else{
$return=false;
}
}else{
$return=false;
}
}else{
$return=false;
}

if(!$return)
$this->errorMess=$this->getError();

return $return;
}
}

private function copyFile(){
if(!$this->errorNum){
$filepath=rtrim($this->filepath, '/').'/';
$filepath.=$this->newFileName;

if(@move_uploaded_file($this->tmpFileName, $filepath)){
return true;
}else{
$this->setOption('errorNum', -3);
return false;
}
}else{
return false;
}
}

//设置和$_FILES有关的内容
private function setFiles($name="", $tmp_name='', $size=0, $error=0){
$this->setOption('errorNum', $error);
if($error){
return false;
}

$this->setOption('originName', $name);
$this->setOption('tmpFileName', $tmp_name);
$arrStr=explode('.', $name); 
$this->setOption('fileType', strtolower($arrStr[count($arrStr)-1]));
$this->setOption('fileSize', $size);

return true;
}

//用于获取上传后文件的文件名
function getNewFileName(){
return $this->newFileName;
}
//上传如果失败，则调用这个方法，就可以查看错误报告
function getErrorMsg() {
return $this->errorMess;
}

/*图片缩放函数
$picname 被缩放后的处理图片源
$maxx    被缩放后的最大宽度
$maxy    被缩放后的最大高度
$pre     被缩放后的图片名的前缀名
*/
function imageupdatesize($picname,$maxx,$maxy,$pre){
     $info=getimagesize($picname);//获取源图片的基本信息

     $w=$info[0]; //获取源图片的宽
     $h=$info[1]; //获取源图片的高

     //获取源图片的类型并为此创建对应的图片资源
     switch($info[2]){
          case 1: //gif
               $im=imagecreatefromgif($picname);
               break;
          case 2:  //jpg
               $im=imagecreatefromjpeg($picname);
               break;
          case 3:  //png
               $im=imagecreatefrompng($picname);
               break;
          default:
               die('图片类型错误');
     }

     //计算缩放比例
     if(($maxx/$w)>($maxy/$h)){
          $b=$maxy/$h;
     }else{
          $b=$maxx/$w;
     }

     //计算出缩放后的尺寸
     $nw=floor($w*$b);
     $nh=floor($h*$b);

     //创建一个新的图像源(缩放后的图片)
     $nim=imagecreatetruecolor($nw,$nh);

     //执行等比缩放
     imagecopyresampled($nim,$im,0,0,0,0,$nw,$nh,$w,$h);

     //输出图像(根据原图像的类型，输出为对应的类型)
     $picinfo=pathinfo($picname);  //解析源图像的名字和路径
     $newpicname=$picinfo["dirname"]."/".$pre.$picinfo["basename"];
     switch($info[2]){
          case 1:
          imagegif($nim,$newpicname);
          break;
          case 2:
          imagejpeg($nim,$newpicname);
          break;
          case 3:
          imagepng($nim,$newpicname);
          break;
     }   

     //释放图片资源
     imagedestroy($im);
     imagedestroy($nim);

     //返回结果
     // return $newpicname;

}

//建立目录函数
function mkdirs($dir){
return is_dir($dir) or ($this->mkdirs(dirname($dir)) and mkdir($dir,0777));
}

/*
根据比例来截取图片的最大面积
$target_ratio 图片的宽高比例，例如1
$file 图片的路径
*/
function cropMaxArea($target_ratio,$file){

$imginfo = getimagesize($file);
$width = $imginfo[0];
$height = $imginfo[1];

$oriRate = $width/$height;
//echo "{$target_ratio}:{$oriRate}";exit;
if ($target_ratio<$oriRate){ //use height as the max
$taget_h = $height;
$taget_w = intval($height*$target_ratio);
$start_x = intval(($width-$taget_w)/2);
$start_y = 0;
$end_x = $start_x+$taget_w;
$end_y = $taget_h;
}else{ //use width as the max
$taget_w = $width;
$taget_h = intval($width/$target_ratio);
$start_x = 0;
$start_y = intval(($height-$taget_h)/2);
$end_x = $taget_w;
$end_y = $start_y+$taget_h;
}
//echo "[{$start_x}]:{$start_y}:{$end_x}:{$end_y}:{$taget_w}:{$taget_h}";
//exit;
$im = imagecreatetruecolor($taget_w,$taget_h);
$thisim = @imagecreatefromjpeg($file);
imagecopy($im,$thisim,0,0,$start_x,$start_y,$end_x,$end_y);
imagejpeg($im,$file,100);
imagedestroy($im);
}

}


